package com.cskaoyan.wordmemorize.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.EmployeeConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.DeleteEmployeeRoleOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.EmployeeDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.request.EmployeeCommand;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    RolePermissionMapper rolePermissionMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    EmployeeConverter employeeConverter;
    @Autowired
    EmployeeRoleMapper employeeRoleMapper;
    @Autowired
    RoleMapper roleMapper;


    @Override
    public EmployeeDTO login(String userName, String password) {

        //将铭文密码转为密文
        String md5Password = SaSecureUtil.md5(password);

        //根据用户名和密码查询数据库
        LambdaQueryWrapper<EmployeeDO> lambdaWrapper = new LambdaQueryWrapper<>();
        lambdaWrapper.eq(EmployeeDO::getName, userName)
                .eq(EmployeeDO::getPassword, md5Password);

        EmployeeDO employeeDO = employeeMapper.selectOne(lambdaWrapper);

        if (employeeDO == null){
            throw new BusinessException(ResultCodeEnum.LOCAL_LOGIN_FAIL);
        }

        return employeeConverter.employeeDO2DTO(employeeDO);

    }

    @Override
    public EmployeeDTO getEmployeeInfo(Long employeeId) {

        EmployeeDO employeeInfo = employeeMapper.getEmployeeInfo(employeeId);
        return employeeConverter.employeeDO2DTO(employeeInfo);
    }

    @Override
    public PageDTO<EmployeeDTO> getEmployeePage(PageRequest request) {
        //如果无参数，则查询所有
        if(request.getPageNum() == null){
            List<EmployeeDO> employeeDOS = employeeMapper.selectList(null);
            //把employeeDOS.size()转换为long
            int size = employeeDOS.size();
            return employeeConverter.emoloyeePage2PageDTO(employeeDOS, (long) size);
        }

        Page<EmployeeDO> page = new Page<>(request.getPageNum(), request.getCount());
        LambdaQueryWrapper<EmployeeDO> queryWrapper1 = new   LambdaQueryWrapper<>();
        //名字模糊匹配
      if(request.getKeyword()!=null){
          queryWrapper1.like(EmployeeDO::getName, request.getKeyword());
      }
        List<EmployeeDO> goodsDOS = employeeMapper.selectList(page, queryWrapper1);
        //把密码设置为空
        for (EmployeeDO employeeDO : goodsDOS) {
            employeeDO.setPassword(null);
        }
        //去关系表查出对应的roleIds


        for (EmployeeDO employeeDO : goodsDOS) {
            List<Long> roleIds =new ArrayList<>();
            LambdaQueryWrapper<EmployeeRoleDO> queryWrapper = new   LambdaQueryWrapper<>();
            queryWrapper.eq(EmployeeRoleDO::getEmployeeId, employeeDO.getId());
            List<EmployeeRoleDO> employeeRoleDOS = employeeRoleMapper.selectList(queryWrapper);
            //赋值
            for(EmployeeRoleDO employeeRoleDO:employeeRoleDOS){
                System.out.println(employeeRoleDO);
                Long roleId = employeeRoleDO.getRoleId();
                roleIds.add(roleId);
            }
            employeeDO.setRoleIds(roleIds);
        }

        return employeeConverter.emoloyeePage2PageDTO(goodsDOS, page.getTotal());

    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_ADD)
    public void addEmployee(EmployeeCommand command) {
        //获取roleid
        List<String> roleIds = command.getRoleIds();
        //员工表插入
        EmployeeDO employeeDO = employeeConverter.command2EmployeeDO(command);
        employeeMapper.insert(employeeDO);
        //员工权限表插入,循环插入
        if(roleIds != null){
            for (String roleId : roleIds) {
                EmployeeRoleDO employeeRoleDO = new EmployeeRoleDO();
                employeeRoleDO.setEmployeeId(employeeDO.getId());
                employeeRoleDO.setRoleId(Long.parseLong(roleId));
                employeeRoleMapper.insert(employeeRoleDO);
            }}

    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateEmployee(EmployeeCommand command) {
        //获取roleid
        List<String> roleIds = command.getRoleIds();
        EmployeeDO employeeDO = employeeConverter.command2EmployeeDO(command);
        employeeMapper.updateById(employeeDO);
        //获取员工id，全部删除
        Long employeeId = employeeDO.getId();
        LambdaQueryWrapper<EmployeeRoleDO> queryWrapper = new   LambdaQueryWrapper<>();
        queryWrapper.eq(EmployeeRoleDO::getEmployeeId,employeeId);
        employeeRoleMapper.delete(queryWrapper);


        if(roleIds != null){
            for (String roleId : roleIds) {
                EmployeeRoleDO employeeRoleDO = new EmployeeRoleDO();
                employeeRoleDO.setEmployeeId(employeeDO.getId());
                employeeRoleDO.setRoleId(Long.parseLong(roleId));
                employeeRoleMapper.insert(employeeRoleDO);
            }}



    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public void delete(Long employeeId) {
        employeeMapper.deleteById(employeeId);
        //删除对应的关系
        LambdaQueryWrapper<EmployeeRoleDO> queryWrapper = new   LambdaQueryWrapper<>();
        queryWrapper.eq(EmployeeRoleDO::getEmployeeId,employeeId);
        employeeRoleMapper.delete(queryWrapper);


    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteEmployeeRoleOperateDTO deleteRole(Long employeeId, Long roleId) {
        LambdaQueryWrapper<EmployeeRoleDO> queryWrapper = new   LambdaQueryWrapper<>();
        queryWrapper.eq(EmployeeRoleDO::getEmployeeId,employeeId).eq(EmployeeRoleDO::getRoleId,roleId);
        RoleDO roleDO = roleMapper.selectById(roleId);
        EmployeeDO employeeDO = employeeMapper.selectById(employeeId);
        DeleteEmployeeRoleOperateDTO deleteEmployeeRoleOperateDTO = new DeleteEmployeeRoleOperateDTO();
        deleteEmployeeRoleOperateDTO.setEmployeeId(employeeId);
        deleteEmployeeRoleOperateDTO.setEmployeeName(employeeDO.getName());
        deleteEmployeeRoleOperateDTO.setRoleId(roleId+"");
        deleteEmployeeRoleOperateDTO.setRoleName(roleDO.getName());
        employeeRoleMapper.delete(queryWrapper);
        return deleteEmployeeRoleOperateDTO;

    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateLoginInfo(Long employeeId, String ip, LocalDateTime time) {

        EmployeeDO employeeDO = new EmployeeDO();
        employeeDO.setId(employeeId);
        employeeDO.setLastLoginIp(ip);
        employeeDO.setLastLoginTime(time);

        employeeMapper.updateById(employeeDO);

    }

    @Override
    public Set<String> getPermissionAlias(Long employeeId) {
        //查employee表获得id
        QueryWrapper<EmployeeDO> Wrapper = new QueryWrapper<>();
        Wrapper.eq("id", employeeId);
        EmployeeDO employeeDO = employeeMapper.selectOne(Wrapper);

        //查employee_role表获得role_id
        QueryWrapper<EmployeeRoleDO> Wrapper2 = new QueryWrapper<>();
        Wrapper2.eq("employee_id", employeeDO.getId());
        List<EmployeeRoleDO> employeeRoleDOS = employeeRoleMapper.selectList(Wrapper2);
        List<Long> roleIds = employeeRoleDOS.stream()
                .map(EmployeeRoleDO::getRoleId)
                .collect(Collectors.toList());

        //查role_permission表获得permission_id
        LambdaQueryWrapper<RolePermissionDO> Wrapper3= new LambdaQueryWrapper<>();
        List<Long> permissionId = new ArrayList<>();
        roleIds.forEach(roleId -> {
            Wrapper3.eq(RolePermissionDO::getRoleId, roleId);
            List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(Wrapper3);
            List<Long> list = rolePermissionDOS.stream()
                    .map(RolePermissionDO::getPermissionId)
                    .collect(Collectors.toList());
            permissionId.addAll(list);
        });

        //查permission表获得权限别名
        LambdaQueryWrapper<PermissionDO> Wrapper4= new LambdaQueryWrapper<>();
        Wrapper4.in(PermissionDO::getId, permissionId);
        List<PermissionDO> permissionDOS = permissionMapper.selectList(Wrapper4);
        List<String> permissionAlias = permissionDOS.stream().map(PermissionDO::getPermissionAlias).collect(Collectors.toList());

        Set<String> permissionAliasSet = new HashSet<String>(permissionAlias);
        return permissionAliasSet;
    }

    @Override
    public boolean saveBatch(Collection<EmployeeDO> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<EmployeeDO> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean updateBatchById(Collection<EmployeeDO> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(EmployeeDO entity) {
        return false;
    }

    @Override
    public EmployeeDO getOne(Wrapper<EmployeeDO> queryWrapper, boolean throwEx) {
        return null;
    }

    @Override
    public Optional<EmployeeDO> getOneOpt(Wrapper<EmployeeDO> queryWrapper, boolean throwEx) {
        return Optional.empty();
    }

    @Override
    public Map<String, Object> getMap(Wrapper<EmployeeDO> queryWrapper) {
        return null;
    }

    @Override
    public <V> V getObj(Wrapper<EmployeeDO> queryWrapper, Function<? super Object, V> mapper) {
        return null;
    }

    @Override
    public BaseMapper<EmployeeDO> getBaseMapper() {
        return null;
    }

    @Override
    public Class<EmployeeDO> getEntityClass() {
        return null;
    }
}